package com.yc.atm;

import org.apache.log4j.Logger;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * @program: concurrent
 * @description:
 * @author: zy
 * @create: 2022-01-15 10:45
 */
public class BankServer {
    private static Logger log= Logger.getLogger(    BankServer.class.getName() );
    public static void main(String[] args) throws IOException {
        //CPU的核心数
        int processors=Runtime.getRuntime().availableProcessors();
        /* 核心线程池的大小 */
        int corePoolSize = processors;
        /* 核心线程池的最大线程数 */
        int maxPoolSize = corePoolSize*2;
        /* 线程最大空闲时间 */
        long keepAliveTime = 10;
        /* 时间单位 */
        TimeUnit unit = TimeUnit.SECONDS;    //  enum枚举.  常量
        /* 阻塞队列 容量为2     最多允许放入两个 空闲任务 */
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(200);
        /* 线程创建工厂 */
        ThreadFactory threadFactory = new NameTreadFactory();
        /* 线程池拒绝策略 */
        RejectedExecutionHandler handler = new MyIgnorePolicy();
        ThreadPoolExecutor executor = null;

        executor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
        /* 预启动所有核心线程  提升效率 */
        executor.prestartAllCoreThreads();


        Bank b=new Bank();
        ServerSocket ss=new ServerSocket( 12000   );
        log.info("银行服务器启动，监听"+ss.getLocalPort()+"端口");
        boolean flag=true;
        while( flag ){
            Socket s=ss.accept();
            System.out.println(  "ATM客户端:"+ s.getRemoteSocketAddress()+"登录了服务器"  );
            //TODO: 商业项目必须用线程池。
           // Thread t=new Thread(   new BankTask(s, b)   );
          //  t.start();

            BankTask task=new BankTask(   s, b   );
            //提交任务到线程池
            executor.submit(task);

        }

        executor.shutdown();
    }



    /**
     * 线程工厂
     */
    static class NameTreadFactory implements ThreadFactory {
        /* 线程id    AtomicInteger 原子类 */
        //原子性  可见性   有序性
        private final AtomicInteger threadId = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable runnable) {
            Thread t = new Thread(runnable, "线程-" + threadId.getAndIncrement()); //  i++　　　=>　ｉ　　Ｉ＋１　　　＝＞　赋值
            //System.out.println(t.getName() + " 已经被创建");
            return t;
        }
    }

    /**
     * 线程池拒绝策略
     */
    public static class MyIgnorePolicy implements RejectedExecutionHandler {
        private Logger log= Logger.getLogger(    MyIgnorePolicy.class .getName() );
        @Override                   //被拒绝的任务             线程池对象.
        public void rejectedExecution(Runnable runnable, ThreadPoolExecutor e) {
            doLog(runnable, e);
        }

        private void doLog(Runnable runnable, ThreadPoolExecutor e) {
            log.error(   "线程池:"+e.toString() + runnable.toString() + " 被拒绝执行");
        }
    }
}
